﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Schema = QASPRibbon.RibbonSchema;

namespace QASPRibbon.Controls
{
    /// <summary>
    /// Represents a Spinner control in the SharePoint Server Ribbon.
    /// </summary>
    public class RibbonSpinner : RibbonButton
    {
        #region Properties

        /// <summary>
        /// An alternative text that is used for the spinner' down arrow.
        /// </summary>
        public string AltDownArrow
        {
            get { return _altDownArrow; }
            set { _altDownArrow = value; }
        }

        /// <summary>
        /// An alternative text that is used for the spinner' down arrow.
        /// </summary>
        public string AltUpArrow
        {
            get { return _altUpArrow; }
            set { _altUpArrow = value; }
        }

        ///<summary>
        /// A value that specifies a factor by which to increase the speed of incrementing or decrementing the value when focus is maintained on the up or down arrow.
        ///</summary>
        public int MultiplierInterval
        {
            get { return _multiplierInterval; }
            set { _multiplierInterval = value; }
        }

        ///<summary>
        /// A value that specifies how much the value increases or decreases when you maintain focus on the up or down button.
        ///</summary>
        public int AccelerationInterval { get; set; }

        /// <summary>
        /// A value that specifies the initial numeric value that is displayed in the control.
        /// </summary>
        public decimal DefaultValue { get; set; }

        /// <summary>
        /// A value that specifies the defual value of this spinner. By default first unit is used for it.
        /// </summary>
        public RibbonSpinnerUnit DefaultUnit { get; set; }

        /// <summary>
        /// Collection of units for use within this spinner control.
        /// </summary>
        public IEnumerable<RibbonSpinnerUnit> Units { get; set; }

        #endregion

        #region Internal

        internal override string XmlTag
        {
            get { return Schema.Spinner; }
        }

        internal override XElement AsXElement()
        {
            var res = base.AsXElement();
            res.Add(new XAttribute(Schema.QueryCommand, FullId + Schema.QueryCommand));
            res.Add(new XAttribute(Schema.AltDownArrow, AltDownArrow));
            res.Add(new XAttribute(Schema.AltUpArrow, AltUpArrow));
            res.Add(new XAttribute(Schema.AccelerationInterval, AccelerationInterval));
            res.Add(new XAttribute(Schema.MultiplierInterval, MultiplierInterval));
            res.Add(new XAttribute(Schema.DefaultValue, DefaultValue));
            var defaultUnit = DefaultUnit ?? Units.FirstOrDefault(x => x.IsDefault) ?? Units.FirstOrDefault();
            if (defaultUnit != null)
            {
                res.Add(new XAttribute(Schema.DefaultUnit, defaultUnit.Title));
            }
            foreach (var unit in Units)
            {
                res.Add(unit.AsXElement());
            }
            return res;
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Creates and initializes a new instance of the RibbonSpinner.
        /// </summary>
        public RibbonSpinner() { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonSpinner.
        /// </summary>
        /// <param name="id">Identifier</param>
        public RibbonSpinner(string id) : base(id) { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonSpinner.
        /// </summary>
        /// <param name="id">Identifier</param>
        /// <param name="title">Title</param>
        public RibbonSpinner(string id, string title) : base(id, title) { }

        #endregion

        #region Private fields

        private string _altDownArrow = string.Empty;
        private string _altUpArrow = string.Empty;
        private int _multiplierInterval = 10;

        #endregion

        #region PostBack Action

        /// <summary>
        /// Occurs when the RibbonSpinner control is clicked.
        /// </summary>
        public new event RibbonSpinnerEventHandler OnAction;

        internal void DoOnAction(RibbonSpinnerEventArgs e)
        {
            var handler = OnAction;
            if (handler != null) handler(this, e);
        }

        #endregion
    }

    /// <summary>
    /// RibbonSpinner event handler
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e">Event arguments</param>
    public delegate void RibbonSpinnerEventHandler(object sender, RibbonSpinnerEventArgs e);

    /// <summary>
    /// Arguments of server ation rised by RibbonSpinner
    /// </summary>
    public class RibbonSpinnerEventArgs : EventArgs
    {
        /// <summary>
        /// Instance of RibbonSpinner
        /// </summary>
        public RibbonButton Instance;

        /// <summary>
        /// Value of RibbonSpinner
        /// </summary>
        public string Value;

        internal RibbonSpinnerEventArgs(RibbonButton button, string arg)
        {
            Instance = button;
            Value = arg;
        }
    }
}
